package com.newy.core.web;

import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.newy.core.util.LangUtils;


/**
 * 身份验证和权限验证 
 * @author linzongxue
 * @date 2011-10-05
 */
public class AuthczFilter implements Filter {
	private static Logger logger = LoggerFactory.getLogger(AuthczFilter.class);
	
	private Set<String> excludedUrls = new HashSet<String>();
	
	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		HttpServletRequest httpRequest = (HttpServletRequest)request;
		HttpServletResponse httpResponse = (HttpServletResponse)response;
		AppContext.bindRequestAndResponse(httpRequest, httpResponse);
		logger.debug(httpRequest.getRemoteAddr() + " --> " + httpRequest.getRequestURI());
		//System.out.print("请求参数：");AppUtils.debug(httpRequest.getParameterMap());
		
		if (authc(httpRequest, httpResponse, chain) && authz(httpRequest, httpResponse, chain)){
			chain.doFilter(request, response);
		}
	}

	/**
	 * 身份验证
	 */
	private boolean authc(HttpServletRequest request, HttpServletResponse response,
			FilterChain chain) throws IOException, ServletException{
		//已经登陆
		if (AppContext.getLoginUser() != null){
			return true;
		}
		//未登陆，但是被排除的URL
		else if (isExcludedUrl(request)){
			chain.doFilter(request, response);
		}
		//未登陆，非法访问
		else{
			logger.debug("访问被拒绝: {}", request.getRequestURI());
			Map<String, Object> r = new HashMap<String, Object>(2);
			r.put("errorType", "no-authc");
			r.put("errorMsg", "身份验证不通过");
			response.setStatus(900);//设置非成功状态，在浏览器中引发异常
			response.getWriter().print(LangUtils.toJson(r));
			response.getWriter().print("/** 可能是登陆超时了，请重新登陆 **/");
		}
		return false;
	}

	/**
	 * 权限验证
	 */
	private boolean authz(HttpServletRequest request, HttpServletResponse response,
			FilterChain chain) throws IOException, ServletException{
		
		return true;
	}
	
	private boolean isExcludedUrl(HttpServletRequest request){
		String uri = request.getRequestURI().substring(request.getContextPath().length() + 1);
		return excludedUrls.contains(uri);
	}
	
	/**
	 * 初始化参数：记住被排除的URL
	 */
	@Override
	public void init(FilterConfig config) throws ServletException {
		String excludes = config.getInitParameter("excludedUrls");
		if (excludes != null){
			for (String url : excludes.split(",|;|\\\t|\\\n")){
				excludedUrls.add(url.trim());
			}
		}
	}

	@Override
	public void destroy() {
		
	}
}
